//
//  BTC+Account+BIP39.swift
//  XHWalletUtils
//
//  Created by xinph on 2020/5/19.
//  Copyright © 2020 xinph. All rights reserved.
//

import Foundation
import XHTokenCore

/// 根据web3创建助记词
extension BTC: BIP39 {
    public static func importWalletFromMne(_ path: String?, password: String, name: String?, mnemonics: String) -> coswift.Promise<Wallet> {
        let promise = coswift.Promise<Wallet>()
        
        //隔离认证路径
        var destPath = ""
        if let path = path {
            destPath = path
        } else {
            destPath = XHTokenCore.BIP44.path(for: Network.accessOnDiffrenceNetwork(), segWit: SegWit.p2wpkh)
        }

        var meta = WalletMeta(chain: .btc, source: .mnemonic)
        //隔离认证
        meta.segWit = SegWit.p2wpkh
        let keystore: BTCMnemonicKeystore
        /// 依赖web3生成助记词
        do {
            ///该函数相当耗时
            keystore = try BTCMnemonicKeystore(password: password, mnemonic: mnemonics, path: destPath, metadata: meta)
            let name = name ?? "Wallet BTC"
            let account = Account(name, address: keystore.address, coin: 0)
            let wallet = BTC(mnemonics, path: destPath, isHD: true, privateKey: keystore.xpri, publicKey: keystore.xpub)
            wallet.mnemonicKeystore = keystore
            
            promise.fulfill(value: wallet)
        } catch {
            promise.reject(error: XHError(mnemonicsError))
            return promise
        }
        return promise

    }
    
    public static func createAccountByMnemonics(_ password: String, name: String) -> coswift.Promise<WalletType> {
        let promise = coswift.Promise<WalletType>()
        
        let password = password
        let bitsOfEntropy: Int = 128 // Entropy is a measure of password strength. Usually used 128 or 256 bits.
        let mnemonics: String
        do {
            mnemonics = try web3swift.BIP39.generateMnemonics(bitsOfEntropy: bitsOfEntropy)!
        } catch {
            promise.reject(error: XHError(createWalletFailure))
            return promise
        }
        //隔离认证路径
        let path = XHTokenCore.BIP44.path(for: Network.accessOnDiffrenceNetwork(), segWit: SegWit.p2wpkh)
        var meta = WalletMeta(chain: .btc, source: .mnemonic)
        //隔离认证
        meta.segWit = SegWit.p2wpkh
        let keystore: BTCMnemonicKeystore
        let keyData: Data
        do {
            keystore = try BTCMnemonicKeystore(password: password, mnemonic: mnemonics, path: path, metadata: meta)
            keyData = try JSONEncoder().encode(keystore.dump())
        } catch {
            promise.reject(error: XHError(createWalletFailure))
            return promise
        }
        let name = name.isEmpty ? "Wallet BTC" : name
        let wallet = BTC(mnemonics, keystore: keyData, path: path, isHD: true, privateKey: keystore.xpri, publicKey: keystore.xpub)
        wallet.mnemonicKeystore = keystore
        let account = Account(name, address: keystore.address, coin: 0)
        Manager.IO.writeWallet(account, wallet: wallet)
        promise.fulfill(value: wallet)
        return promise
    }

    public static func importAccountByMnemonics(_ password: String, name: String, mnemonics: String, saveToLocal: Bool) -> coswift.Promise<WalletType> {
        let promise = coswift.Promise<WalletType>()
        
        guard !mnemonics.isEmpty, mnemonics.split(separator: " ").count >= 12 else {
            promise.reject(error: XHError(mnemonicsLengthError))
            return promise
        }
        //隔离认证路径
        let path = XHTokenCore.BIP44.path(for: Network.accessOnDiffrenceNetwork(), segWit: SegWit.p2wpkh)
        var meta = WalletMeta(chain: .btc, source: .mnemonic)
        //隔离认证
        meta.segWit = SegWit.p2wpkh
        let keystore: BTCMnemonicKeystore
        /// 依赖web3生成助记词
        do {
            ///该函数相当耗时
            keystore = try BTCMnemonicKeystore(password: password, mnemonic: mnemonics, path: path, metadata: meta)
            let name = name.isEmpty ? "Wallet BTC" : name
            let account = Account(name, address: keystore.address, coin: 0)
            let wallet = BTC(mnemonics, path: path, isHD: true, privateKey: keystore.xpri, publicKey: keystore.xpub)
            wallet.mnemonicKeystore = keystore
            if saveToLocal {
                Manager.IO.writeWallet(account, wallet: wallet)
            }
            
            promise.fulfill(value: wallet)
        } catch {
            promise.reject(error: XHError(mnemonicsError))
            return promise
        }
        return promise
    }
}
